﻿#include <iostream>
using namespace std;

////9. 基于范围的for循环(C++11)
////9.1 范围for的语法
////对于一个有范围的集合而言，由程序员来说明循环的范围是多余的，有时候还会容易犯错误。
////因此C++11中引入了基于范围的for循环。
////for循环后的括号由冒号“ ：”分为两部分：第一部分是范围内用于迭代的变量，第二部分则表示被迭代的范围。
//int main() {
//	int a[] = { 1, 2, 3, 4, 5 };
//	for (int i = 0; i < sizeof(a) / sizeof(a[0]); ++i)
//		a[i] *= 2;
//
//	for (int i = 0; i < sizeof(a) / sizeof(a[0]); ++i)
//		cout << a[i] << " ";
//	cout << endl;
//
//	//范围for
//	//依次取数组中的数据复制给e
//	//自动判断结束
//	//自动迭代
//	for (auto e : a) //auto换成int也可以，因为数组元素是int类型
//		cout << e << " ";
//	cout << endl;
//
//
//	////无效，数组数据不会变化。因为这里是依次取数组的值赋值给x
//	////x的改变不影响数组的值
//	//for (auto x : a) //错误版本
//	//	x *= 2;
//
//	//正确版本
//	for (auto& x : a)
//		x *= 2;
//}



////9.2 范围for的使用条件
////1. for循环迭代的范围必须是确定的
////对于数组而言，就是数组中第一个元素和最后一个元素的范围；
////对于类而言，应该提供begin和end的方法，begin和end就是for循环迭代的范围。
////注意：以下代码就有问题，因为for的范围不确定
//void TestFor(int array[]) {
//	for (auto& e : array) //范围for 这里的array针对的是数组名。不管是C还是C++传过来的是指针
//		cout << e << endl;
//}



//10. 指针空值nullptr(C++11)

//#ifndef NULL
//#ifdef __cplusplus
//#define NULL   0
//#else
//#define NULL   ((void *)0)
//#endif
//#endif
//上方为C++98
void f(int i) {
	cout << "f(int)" << endl;
}
void f(int* p) {
	cout << "f(int*)" << endl;
}
int main() {
	f(0);         //f(int)
	f(NULL);      //f(int)
	f((int*)NULL);//f(int*)
	return 0;
}
//程序本意是想通过f(NULL)调用指针版本的f(int*)函数，但是由于NULL被定义成0，因此与程序的初衷相悖
//在C++98中，字面常量0既可以是一个整形数字，也可以是无类型的指针(void*)常量，
//但是编译器默认情况下将其看成是一个整形常量，如果要将其按照指针方式来使用，必须对其进行强转(void*)0。
//注意：
//1. 在使用nullptr表示指针空值时，不需要包含头文件，因为nullptr是C++11作为新关键字引入的。
//2. 在C++11中，sizeof(nullptr) 与 sizeof((void*)0)所占的字节数相同。
//3. 为了提高代码的健壮性，在后续表示指针空值时建议最好使用nullptr。

void TestPtr() {
	int* p1 = NULL;
	int* p2 = 0;
}